<?php

namespace App\Livewire;


use App\Models\ComponentType;
use Illuminate\Support\Facades\DB;
use Illuminate\View\View;
use Livewire\Component;
use Filament\Actions\Concerns\InteractsWithActions;
use Filament\Actions\Contracts\HasActions;
use Filament\Forms\Concerns\InteractsWithForms;
use Filament\Forms\Contracts\HasForms;
use Filament\Actions\Action;
use App\Models\Component as ComponentModel;
use Filament\Support\Enums\Alignment;
use App\Models\Project;
use Filament\Notifications\Notification;
use Filament\Forms\Components\TextInput;


class ComponentList extends Component implements HasForms, HasActions
{
    use InteractsWithForms, InteractsWithActions;

    public $project_id;
    public $save_status;
    public function mount(?string $project_id = null, ?string $save_status = null): void
    {
        $this->project_id = $project_id;
        $this->save_status = $save_status;
    }
    public function render()
    {
        $project_id = $this->project_id;
        $component_ids = DB::table('component_project_type')->where('project_id', $project_id)->pluck('component_id')->toArray();

        $components = ComponentModel::whereNotIn('id', $component_ids)->paginate(50);

        if($this->save_status === 'saved'){
            $components = ComponentModel::whereIn('id', $component_ids)->paginate(50);
        }

        return view('livewire.component-list', compact('components', 'project_id'));
    }

    public function viewDetailAction():Action
    {
        return Action::make('viewDetail')
            ->modalHeading(function(array $arguments){
                $id = $arguments['id'];
                return ComponentModel::findOrFail($id)->title;
            })
            ->action(function(array $arguments){

                $id = $arguments['id'];

                $project_id = $arguments['project_id'];

                $download_path = ComponentModel::findOrFail($id)->download_path;

                $project_type = Project::findOrFail($project_id)->project_type;

                $component_type_id = ComponentModel::findOrFail($id)->componentTypes()->where('framework', $project_type)->first()->id;

                $framework = ComponentType::findOrFail($component_type_id)->framework;

                $component_type_code = ComponentType::findOrFail($component_type_id)->code;

                $this->saveComponentProject($component_type_id, $project_id);

                $project_path = storage_path('app/projects/' . auth()->id(). '/'. $framework.'/'.$project_id.'/components/'.$download_path);

                if(!is_dir($project_path)){
                    mkdir($project_path, 0755, true);
                }

                $file_extension = 'vue';

                if($framework === 'react'){
                    $file_extension = 'jsx';
                }

                if($framework === 'blade'){
                    $file_extension = 'blade.php';
                }

                $file_name = ComponentModel::findOrFail($id)->slug;

                $component_file = $project_path . '/' . $file_name . '.' . $file_extension;

                file_put_contents($component_file, $component_type_code);

                Notification::make('added to project')
                     ->title('成功添加到了项目中！')
                     ->success()
                     ->send();

            })->modalContent(
                fn (array $arguments): View => view(
                    'livewire.component-detail',
                    ['id' => $arguments['id'], 'project_id' => $arguments['project_id'], 'component' => ComponentModel::findOrFail($arguments['id'])],
                )
            )
            ->modalWidth('7xl')
            ->modalSubmitActionLabel('添加到此项目')
            ->after(function(array $arguments){
                return redirect()->route('/user/components/'.$arguments['project_id'].'/saved');
            })->modalSubmitAction(function(array $arguments)
            {
                $id = $arguments['project_id'];
                if($id === 0){
                    return false;
                }
            })
            ->modalCancelAction(false)
            ->modalFooterActionsAlignment(Alignment::Right);
    }

    public function saveComponentProject($component_type_id, $project_id)
    {

        $component = $component_type_id;

        $project = $project_id;

        $included_component_type_ids = ComponentType::find($component)->included_component_type_ids;

        if($included_component_type_ids == null){

            $exists = DB::table('component_project_type')->where('component_type_id', $component)->where('project_id', $project)->exists();

            if (!$exists) {
                DB::table('component_project_type')->insert([
                    'component_type_id' => $component,
                    'component_id' => ComponentType::find($component)->component->id,
                    'project_id' => $project,
                    'created_at' => now(),
                    'updated_at' => now(),
                ]);

                return ['success' => true];
            }
        }else{

            array_push($included_component_type_ids, $component);

            foreach($included_component_type_ids as $included_component_type_id){
                $exists = DB::table('component_project_type')->where('component_type_id', $included_component_type_id)->where('project_id', $project)->exists();

                if(!$exists){
                    DB::table('component_project_type')->insert([
                        'component_type_id' => $included_component_type_id,
                        'component_id' => ComponentType::find($included_component_type_id)->component->id,
                        'project_id' => $project,
                        'created_at' => now(),
                        'updated_at' => now(),
                    ]);

                    return ['success' => true];
                }
            }
        }

        return ['success' => true];
    }
}
